package com.sharding.order.sharding.algorithm;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * B端维度分表路由算法类
 */
public class OrderTableShardingByMerchantAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {

    @Override
    public Collection<String> doSharding(Collection<String> tables, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
        Collection<Comparable<?>> orderNos = shardingValue.getColumnNameAndShardingValuesMap().get("order_no");
        Collection<Comparable<?>> merchantIds = shardingValue.getColumnNameAndShardingValuesMap().get("merchant_id");
        Set<String> actualDbNames = null;
        if (CollectionUtils.isNotEmpty(orderNos)) {
            actualDbNames = orderNos.stream()
                    .map(orderNo -> {
                        String orderNoStr = String.valueOf(orderNo);
                        //截取出来的字符串是merchantId的后三位
                        String merchantIdSuffix = StringUtils.substring(orderNoStr, orderNoStr.length() - 6, orderNoStr.length() - 3);
                        return getActualDbName(merchantIdSuffix, tables);
                    })
                    .collect(Collectors.toSet());
        } else if (CollectionUtils.isNotEmpty(merchantIds)) {
            actualDbNames = merchantIds.stream()
                    .map(merchantId -> {
                        String merchantIdStr = String.valueOf(merchantId);
                        //截取merchantId的后三位
                        String merchantIdSuffix = StringUtils.substring(merchantIdStr, merchantIdStr.length() - 3);
                        return getActualDbName(merchantIdSuffix, tables);
                    })
                    .collect(Collectors.toSet());
        }

        return actualDbNames;
    }

    public String getActualDbName(String shardingValue, Collection<String> tables) {
        //使用merchantId后三位进行路由
        int dbSuffix = shardingValue.hashCode() / tables.size() % tables.size();
        for (String table : tables) {
            if (table.endsWith(String.valueOf(dbSuffix))) {
                return table;
            }
        }
        return null;
    }

}